package com.imu.purse.admin.controller.business;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.imu.common.annotation.SysLog;
import com.imu.common.exception.ErrorDesc;
import com.imu.common.utils.R;
import com.imu.common.validator.ValidatorUtils;
import com.imu.common.validator.group.AddGroup;
import com.imu.common.validator.group.UpdateGroup;
import com.imu.constant.Constant;
import com.imu.purse.bean.CoreMoneyAddr;
import com.imu.purse.modules.app.entity.ImuUserEntity;
import com.imu.purse.modules.app.entity.ImuUserLogEntity;
import com.imu.purse.modules.app.entity.RateEntity;
import com.imu.purse.modules.app.service.ImuUserLogService;
import com.imu.purse.modules.app.service.ImuUserService;
import com.imu.purse.modules.app.service.impl.RateServiceImpl;
import com.imu.purse.modules.bitcoin.BitcoinApi;
import com.imu.purse.modules.sys.entity.SysUserEntity;
import com.imu.purse.modules.trade.entity.FundEntity;
import com.imu.purse.modules.trade.entity.TradeBehindEntity;
import com.imu.purse.modules.trade.service.FundService;
import com.imu.purse.modules.trade.service.TradeInfoService;
import com.imu.security.ISessionTokenProvider;
import com.imu.security.SessionTokenProviderFactory;
import com.qiniu.util.StringUtils;
import com.xiaoleilu.hutool.bean.BeanUtil;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;



/**
 * 用户信息
 * @author sunhongwei
 * @email sunhongwei@jshijian.com
 * @date 2018-04-16 10:19:21
 * Copyright (c) 2017 武汉极时间科技有限公司 版权所有 
 * Jshijian aloha CO.,LTD. All Rights Reserved. 
 */
/**
 * @author Administrator
 *
 */
@RestController
@RequestMapping("user")
public class UserController extends com.imu.purse.modules.sys.controller.AbstractController
{
	/****
	 * 查询用户信息
	 * @param params
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("查询用户信息")
	@GetMapping("/list")
	@RequiresPermissions("user:list")
	public R list( @RequestParam Map<String, Object> params)
	{
		R r = R.ok();
		ImuUserEntity dto = BeanUtil.mapToBean(params, ImuUserEntity.class, true);
		if(null == dto || StrUtil.isBlank(dto.getP())) return r;
		
		if(null != dto && StrUtil.isBlank(dto.getSts()))
		{
			dto.setSts(DateUtil.beginOfYear(new Date()).toString());
		}
		if(null != dto && StrUtil.isBlank(dto.getEts()))
		{
			dto.setEts(DateUtil.endOfYear(new Date()).toString());
		}
 		List<ImuUserEntity> dtos = service.queryList(dto);
		return r.put("page", new PageInfo<ImuUserEntity>(dtos));
	}
	
	/****
	 * 根据ID查询用户信息
	 * @param id
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("根据ID查询用户信息")
	@GetMapping("/info/{id}")
	@RequiresPermissions("user:info")
	public R info(@PathVariable("id") Long id)
	{
		ImuUserEntity entity = service.findById(id);
		return R.ok().put("dto",entity );
	}
	
	/****
	 * 新增用户信息
	 * @param dto
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("新增用户信息")
	@PostMapping("/save")
	@RequiresPermissions("user:save")
	public R save(@RequestBody ImuUserEntity dto)
	{
		ValidatorUtils.validateEntity(dto, AddGroup.class);
		/*dto.setUserCreate(this.getUserId());
		dto.setUserUpdate(this.getUserId());*/
		service.save(dto,"");
		return R.ok();
	}
	
	/****
	 * 修改用户信息
	 * @param dto
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("修改用户信息")
	@PostMapping("/update")
	@RequiresPermissions("user:update")
	public R update(HttpServletRequest request,@RequestBody ImuUserEntity dto)
	{
//		String browserLanguage=request.getHeader("Accept-Language");
//    	browserLanguage=browserLanguage.substring(0, 2);//截取浏览器语言的前两位   判断是中文还是英文
		ValidatorUtils.validateEntity(dto, UpdateGroup.class);
		//dto.setUserUpdate(this.getUserId());
		//验证是否当前手机号已经存在
		ImuUserEntity imuUser=service.queryByMobile(dto.getPhone());
        if(imuUser!=null){
        	return R.error(ErrorDesc.PHONE_REG.getCode(), ErrorDesc.PHONE_REG.getMsg());
        }
		service.updatePhone(dto);
		return R.ok();
	}
	
	/****
	 * 删除用户信息
	 * @param ids
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("删除用户信息")
	@PutMapping("/delete")
	@RequiresPermissions("user:delete")
	public R delete(@RequestBody String[] ids)
	{
		service.delete(ids);
		return R.ok();
	}
	
	/****
	 * 锁定用户信
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("锁定用户信息")
	@PutMapping("/lock")
	@RequiresPermissions("user:lock")
	public R lock(@RequestBody ImuUserEntity dto)
	{
		String remark=dto.getAddress();
		dto.setAddress(null);
		service.update(dto);
		Integer	operaction=null;
		if(null!=dto.getState()&&Constant.User.ACTIVE==dto.getState()){
			operaction=Constant.UserLog.USER_UNLOCK;
		}else{
			operaction=Constant.UserLog.USER_LOCK;
			//删除用户缓存session
			ISessionTokenProvider sessionProvider = SessionTokenProviderFactory.getSessionTokenProvider();
			//直接剔除所有pc和移动端的   防止pc端和移动端同时在线
			String eliminate = SecureUtil.md5(dto.getId() + Constant.MOBILE);
			sessionProvider.removeSession(eliminate);
			eliminate = SecureUtil.md5(dto.getId() + Constant.PC);
			sessionProvider.removeSession(eliminate);
		}
		String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();

		userLogService.insertUserLog(dto.getId().intValue(),username,dto.getPhone(),operaction,remark);
		return R.ok();
	}

	@SysLog("锁定用户转账")
	@PutMapping("/locktrans")
	@RequiresPermissions("user:locktrans")
	public R locktrans(@RequestBody ImuUserEntity dto)
	{
		String remark =dto.getAddress();
		dto.setAddress(null);
		service.update(dto);

		String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
		Integer	operaction=null;
		if(null!=dto.getStatetrans()&&Constant.User.ACTIVE==dto.getStatetrans()){
			operaction=Constant.UserLog.ZZ_UNLOCK;
		}else{
			operaction=Constant.UserLog.ZZ_LOCK;
		}
		userLogService.insertUserLog(dto.getId().intValue(),username,dto.getPhone(),operaction,remark);
		return R.ok();
	}


	/**
	 * 提供给接口调用
	 * @param dto
	 * @return
	 */
	@PutMapping("/lockuser")
	public R lockuser(@RequestBody ImuUserEntity dto)
	{
		service.updateByPhone(dto);
		return R.ok();
	}
	
    @RequestMapping(value = "imports", method=RequestMethod.POST)
	@RequiresPermissions("user:import")
	public R upload(@RequestParam("file") MultipartFile[] myfiles, HttpServletRequest request) throws Exception {
		StringBuffer buffer=new StringBuffer();
		String originalFilename="";//上传的文件的文件名
		String suffix="";
		
		int i = 0;
		for (MultipartFile myfile : myfiles) {
			if (!myfile.isEmpty()) {
				//获得文件后缀名
				suffix = myfile.getOriginalFilename().substring(myfile.getOriginalFilename().lastIndexOf("."));
				//获得文件源名
				originalFilename=myfile.getOriginalFilename();
				//强转为File
				String path=request.getSession().getServletContext().getRealPath("/upload/");
				File file = new File(path);
				if  (!file .exists()  && !file .isDirectory())      
				{       
				    System.out.println("//不存在");  
				    file .mkdir();    
				}
				suffix = myfile.getOriginalFilename().substring(myfile.getOriginalFilename().lastIndexOf(".")); 
				String fileName = UUID.randomUUID().toString()+ suffix; 
				File f=new File(path,fileName);
				try {
				myfile.transferTo(f);
				i=service.saveFile(f,request);
				} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}
			}
		}
		if(i==1){
			return R.ok(1).put("msg", "导入成功");
		}else{
        	return R.error(ErrorDesc.MONEY_PACK_ADDR_ERROR.getCode(), ErrorDesc.MONEY_PACK_ADDR_ERROR.getMsg());
		}
		
    }
	/****
	 * 显示用户金额
	 * @param phone
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("显示用户金额")
	@GetMapping("/showMoney")
	@RequiresPermissions("user:list")
	public R showUserMoney(String phone){
		ImuUserEntity entity = null;
		String userStr = redisTemplate.opsForValue().get(phone);
		if(StringUtils.isNullOrEmpty(userStr)){
			entity = this.service.queryByMobile(phone);
			//
		}else{
			entity = JSON.parseObject(userStr, ImuUserEntity.class);
		}
		//根据用户id获取资金信息
		FundEntity fEntity = fundService.findByUserId(entity.getId());
		return R.ok().put("fundEntity", fEntity);
	}
	
	/****
	 * 完成后台转账功能
 	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("完成后台转账")
	@PostMapping("/transferBehind")
	@RequiresPermissions("user:list")
	public R showUserMoney(@RequestBody TradeBehindEntity form){
		//转出账号核心钱包地址
		String outAccount=redisTemplate.opsForValue().get(form.getFromAccount().toString());
		String inAccount=redisTemplate.opsForValue().get(form.getToPhone().toString());
		if(null == outAccount){
			return R.error(ErrorDesc.GET_USER_ERR.getCode(), ErrorDesc.GET_USER_ERR.getMsg());
		}else if (null == inAccount ) {
			return R.error(ErrorDesc.MONEY_PACK_ADDR_INVALIDE.getCode(), ErrorDesc.MONEY_PACK_ADDR_INVALIDE.getMsg());
		}
		//转出人信息
		ImuUserEntity imuOutPerson = JSON.parseObject(outAccount, ImuUserEntity.class);
		//接收人信息
		ImuUserEntity imuInPerson= JSON.parseObject(inAccount, ImuUserEntity.class);
		//转出账号核心钱包地址
		Object ob = redisTemplate.opsForHash().get(Constant.USER_CORE_MONEY_KEY,imuOutPerson.getId().toString());
		//转入账号核心钱包地址
		Object toPhoneMoney = redisTemplate.opsForHash().get(Constant.USER_CORE_MONEY_KEY,imuInPerson.getId().toString());
		FundEntity fEntity = fundService.findByUserId(imuInPerson.getId());
		String formAccount=form.getFromAccount();//转出人的手机号
		String address = fEntity.getMoneyAddress();//接收人钱包地址
		//获取汇率
		BigDecimal bmoney=new BigDecimal(form.getToAmount());
		BigDecimal rate = Constant.DEFAULT_RATE;
		RateEntity entity = new RateEntity();
			entity.setRate(bmoney);
			entity = rateServiceImpl.selectByRate(entity);
			if(null != entity){//表示没查到值
		        	rate = entity.getRate();
			}
		//转账人钱包地址   ==ob
		CoreMoneyAddr coreAddr = JSON.parseObject(ob.toString(),CoreMoneyAddr.class);
		if(ob.toString().equals(toPhoneMoney.toString())){//转出人与转账人核心钱包地址相同

			boolean boo = bitcoinApi.movetoaddress(formAccount, address, bmoney, new BigDecimal(0), ob.toString());
			if(boo){
				service.transaction(imuOutPerson, imuInPerson, form.getToAmount(),0,new BigDecimal(0),null);
				
			}else {
				return R.error(ErrorDesc.MONEY_PACK_LIMIT.getCode(), ErrorDesc.MONEY_PACK_LIMIT.getMsg());
			}
		}else {
			//transId==交易ID

			String transId = bitcoinApi.sendfrom(formAccount, address, bmoney,rate, ob.toString());

			if(StringUtils.isNullOrEmpty(transId)){
				return R.error(ErrorDesc.MONEY_PACK_LIMIT.getCode(), ErrorDesc.MONEY_PACK_LIMIT.getMsg());
            }
			service.transaction(imuOutPerson, imuInPerson, form.getToAmount(),1,rate,transId);
		}
		
		return R.ok().put("result", 1);
		
	}

	/****
	 * 完成后台转账功能
	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("修改国际号码")
	@PutMapping("/concatPhone")
	@RequiresPermissions("user:concatPhone")
	public R concatPhone(@RequestBody ImuUserEntity entity){
		if(entity.getId() == null || StringUtils.isNullOrEmpty(entity.getPhone())
				|| StringUtils.isNullOrEmpty(entity.getInterPhone())){
			return R.error(0,"部分值为空");
		}

		//获取备注信息
		String remark =entity.getAddress();
		entity.setAddress(null);
		//修改国际号码
		service.concatPhone(entity);
		String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
		userLogService.insertUserLog(entity.getId().intValue(),username,entity.getInterPhone(),Constant.UserLog.PHONE_CHANGE,remark);

		return R.ok();
	}



	/****
	 * 查询用户信息
	 * @param params
	 * @date 2018-04-16 10:19:21
	 * @return
	 */
	@SysLog("查询用户操作日志")
	@GetMapping("/userLogList")
	@RequiresPermissions("user:userLogList")
	public R userLogList( @RequestParam Map<String, Object> params)
	{
		R r = R.ok();
		ImuUserLogEntity dto = BeanUtil.mapToBean(params, ImuUserLogEntity.class, true);
		List<ImuUserLogEntity> dtos = userLogService.queryList(dto);
		return r.put("page", new PageInfo<ImuUserLogEntity>(dtos));
	}
	
	@Autowired
	private ImuUserService service;
	@Autowired
	private ImuUserLogService userLogService;
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	@Autowired
	private FundService fundService;
	@Autowired
	private BitcoinApi bitcoinApi;
	@Autowired
	private RateServiceImpl rateServiceImpl;
	@Autowired
	private TradeInfoService tradeInfoService;
	
}
